﻿using System.Collections.Generic;
using System.Linq;
using System.Web.UI;
using Ext.Net;
using Ext.Net.Utilities;
using KamLib.Controls;

namespace KamLib
{

    public interface IGridContainer : IEquipContainer
    {
        GridPanel Grid { get; }
        bool IsLocal { get; }
        bool CanEdit { get; }
        bool CanDelete { get; }
        bool CanInsert { get; }
        int PageSize { get; }
        EntityDescAttribute EntityDesc { get; }
        object cmdAdd { get; set; }
    }
    public interface IStoreContainer : IEquipContainer
    {
        Store Store { get; set; }
        string GroupField { get; }
        string KeyField { get; }
        string SortField { get; }
        SortDirection SortDir { get; }
    }


    public static class GridEquiper
    {

        public static void Apply(EquipInterfaceContainer c)
        {
            var igrid = c.Get<IGridContainer>();
            if (igrid != null) Apply(igrid);
        }

        public static void Apply(IGridContainer c)
        {
            var grid = c.Grid;

            if (grid.StoreID.IsEmpty() && grid.Store.Count == 0)
            {
                var istore = c.Owner.Get<IStoreContainer>();
                if (istore != null)
                {
                    istore.Store = NewStore(c, istore);
                    grid.Store.Add(istore.Store);
                }
            }

            grid.StripeRows = true;
            grid.TrackMouseOver = true;
            grid.LoadMask.ShowMask = true;
            grid.SaveMask.ShowMask = true;
            if (grid.SelectionModel.Count == 0)
                grid.SelectionModel.Add(new RowSelectionModel { SingleSelect = true });
            AddToolbars(c);

            var compact = c.Grid.ClicksToEdit == 1;

            if (compact)
                grid.Listeners.Command.Handler = "KamLib.Logic.Grid.execCompactCommand(this, record, command);";

            GridCommand col1 = null, col2 = null;
            MenuCommand col3 = null;

            if (c.Grid.ClicksToEdit == 2 && c.CanEdit)
            {
                col1 = new GridCommand
                {
                    IconCls = "icon-form_yellow_edit-16",
                    Text = "Edit",
                    CommandName = "edit",
                };
                col1.ToolTip.Text = "Edit";
            }
            else if (c.Grid.ClicksToEdit == 1 && c.CanEdit)
            {
                foreach (var col in c.Grid.ColumnModel.Columns)
                {
                    if (col.Editor.Count > 0) continue;
                    var cf = col as IColumnEditorFactory;
                    if (cf != null)
                        col.Editor.Add(cf.NewEditor());
                }
            }

            if (c.CanDelete)
            {
                col3 = new MenuCommand
                {
                    Text = "Delete",
                    IconCls = "icon-delete2-16",
                    HideOnClick = false,
                };
                col3.Menu.Items.Add(new MenuCommand
                {
                    Text = "Delete " + c.EntityDesc.Name,
                    CommandName = "delete",
                });
            }

            if (col3 != null)
            {
                col2 = new GridCommand
                {
                    IconCls = "icon-navigate_close-16",
                };
                col2.ToolTip.Text = "Row Menu";
                col2.Menu.EnableScrolling = false;
                col2.Menu.Items.Add(col3);
            }


            if (col1 != null || col2 != null)
            {
                var width = 0;
                var cmdCol = new CommandColumn { MenuDisabled = true };
                if (col1 != null)
                {
                    width += 46;
                    cmdCol.Commands.Add(col1);
                }
                if (col2 != null)
                {
                    width += 35;
                    cmdCol.Commands.Add(col2);
                }
                cmdCol.Width = width;
                grid.ColumnModel.Columns.Add(cmdCol);
            }
        }

        private static Store NewStore(IGridContainer gc, IStoreContainer c)
        {

            var store = new Store
            {
                ID = gc.Grid.ID + "_Store",
                AutoLoad = false,
                RemoteSort = true,
                GroupField = c.GroupField,
                SortInfo = { Field = c.SortField.IfNull(c.KeyField), Direction = c.SortDir },
                BaseParams =
                {
                    new Parameter { Name = "start", Value = "" },
                    new Parameter { Name = "limit", Value = "" },
                    new Parameter { Name = "group", Value = "" },
                    new Parameter { Name = "sort", Value = "" },
                    new Parameter { Name = "dir", Value = "" },
                    new Parameter { Name = "gridfilters", Value = "" },
                    new Parameter { Name = "monitorId", Value = "" },
                },
                Reader = 
                {
                    new JsonReader { IDProperty = c.KeyField, Root = "d.Data", TotalProperty = "d.TotalRecords",  }
                },
            };

            return store;
        }

        private static void AddToolbars(IGridContainer c)
        {
            ToolbarBase tb = null;
            var cmps = new List<Component>();

            var local = c.IsLocal;
            var compact = c.Grid.ClicksToEdit == 1;

            if (!local && c.PageSize > 0)
            {
                tb = new PagingToolbar
                {
                    ID = c.Grid.ID + "_Pager",
                    PageSize = c.PageSize,
                    DisplayInfo = true,
                    DisplayMsg = "Displaying " + c.EntityDesc.Names + " {0} - {1} of {2}",
                    EmptyMsg = "No " + c.EntityDesc.Name + " to display",
                    Height = 28,
                };
                if (!compact) tb.Items.Add(new ToolbarSeparator());
            }
            else if (c.CanInsert)
            {
                tb = new Toolbar
                {
                    ID = c.Grid.ID + "_TB",
                    Flat = compact,
                    Height = 28,
                };

                if (!local)
                {
                    cmps.Add(new Button
                    {
                        //ID = c.Grid.ID + "_cmdRefresh",
                        IconCls = "x-tbar-loading",
                        OnClientClick = GetRefreshScript(c),
                    });
                    if (!compact) cmps.Add(new ToolbarSeparator());
                }
            }

            if (c.CanInsert)
            {
                if (c.IsLocal)
                {
                    cmps.Add(new Button
                    {
                        IconCls = "icon-copy-16",
                        OnClientClick = "KamLib.Logic.Grid.copyRowsToClipboard(null)",
                        ToolTip = "Copy all rows to clipboard",
                    });
                    cmps.Add(new Button
                    {
                        IconCls = "icon-paste-16",
                        OnClientClick = "KamLib.Logic.Grid.pasteRowsFromClipboard(" + c.Grid.ClientID + ")",
                        ToolTip = "Paste rows from clipboard",
                    });
                }

                cmps.Add(new ToolbarFill());
                if (!local) cmps.Add(new ToolbarSeparator());

                cmps.Add((Button)(c.cmdAdd = new Button
                {
                    //ID = c.Grid.ID + "_cmdAdd",
                    IconCls = "icon-add2-16",
                    Text = "Add " + c.EntityDesc.Name,
                    OnClientClick = c.IsLocal ? "KamLib.Logic.Grid.addRow(" + c.Grid.ClientID + ", true)" : null,
                }));
            }

            if (!(tb is PagingToolbar) && (tb == null || cmps.Count <= 0)) return;
            tb.Items.AddRange(cmps);
            c.Grid.TopBar.Add(tb);

            if (tb is PagingToolbar)
                c.Grid.CustomConfig.Add(new ConfigItem { Name = "pager", Value = tb.ClientID, Mode = ParameterMode.Value });
        }

        public static string GetRefreshScript(IGridContainer gc)
        {
            if (gc == null || gc.Grid == null) return null;

            var pager = gc.Grid.TopBar.OfType<PagingToolbar>().FirstOrDefault();
            if (pager != null)
                return pager.ClientID + ".doRefresh();";

            var store = gc.Owner.Get<IStoreContainer>().Store ?? gc.Grid.Store.FirstOrDefault();
            if (store != null)
                return store.ClientID + ".reload();";

            return null;
        }

        public static TabStrip MakeTabStriped(ContainerBase parent, int width, params GridPanel[] grids)
        {
            if (grids.Length < 2) return null;

            var ts = new TabStrip { Width = width };

            foreach (var grid in grids)
            {
                ts.Items.Add(new TabStripItem(grid.Title.IfNull(grid.ID))
                {
                    ActionItem = grid,
                    TabTip = grid.TabTip,
                });
                grid.Header = false;

                ToolbarBase tb;
                if (grid.TopBar.Count == 0)
                    grid.TopBar.Add(tb = new Toolbar { Height = 27 });
                else
                {
                    tb = grid.TopBar.Last();
                    if (tb.Items.OfType<ToolbarFill>().FirstOrDefault() == null)
                        tb.Items.Add(new ToolbarFill());
                    tb.Items.Add(new ToolbarSeparator { Width = 20 });
                }
                tb.Items.Add(new ToolbarSpacer(width));
            }

            parent.Items.Add(ts);
            ts.StyleSpec = "z-index:9999;position:absolute;top:4px;left:100%;margin-left:-" + width + "px;";

            return ts;
        }
    }
}